#ifndef VIA_COMMANDS_INTERNAL_H__
#define VIA_COMMANDS_INTERNAL_H__

#include "commands.h"
#include <TLHELP32.H>

class CViaCmds {
public:
	CViaCmds() {
		m_sztExpression = NULL;
		m_ctExpression = 0;
		m_szExpression = NULL;
		m_cExpression = 0;
	}
	CViaCmds(PVOID pApp) {
		m_sztExpression = NULL;
		m_ctExpression = 0;
		m_szExpression = NULL;
		m_cExpression = 0;
		Init(pApp);
	}
	virtual ~CViaCmds() { 
		Release(); 
	}
	virtual BOOL	Init(PVOID pApp) {
		AllocExp(1024);
		AllocExp_t(1024);
		return TRUE;
	}
	virtual void	Release() {
		FreeExp();
		FreeExp_t();
	}
	virtual BOOL	Evaluate(char* exp, PVOID value, VIA_DATATYPE type = VIA_INT) = 0;
	virtual BOOL	Evaluate(char* exp, TCHAR* value, int size) = 0;
	virtual	BOOL	ReadFromMemory(PBYTE pDst, PBYTE pSrc, long size) = 0;

protected:
	BOOL	AllocExp(int size) {
		if (m_szExpression && size + 1 <= m_cExpression) {
			wmemset(m_szExpression, 0, m_cExpression);
			return TRUE;
		}

		if (m_szExpression) {
			delete [] m_szExpression;
			m_cExpression = 0;
		}

		size += 10;
		if (size < 256)
			size = 256;
		m_szExpression = new WCHAR[size];
		m_cExpression = size;
		wmemset(m_szExpression, 0, size);
		return TRUE;
	}
	void	FreeExp() {
		if (m_szExpression)
			delete [] m_szExpression;
		m_szExpression = NULL;
		m_cExpression = 0;
	}
	BSTR	GetBSExpression(char* szExp) {
		size_t n = strlen(szExp);
		AllocExp(n);
		if (0 == mbstowcs_s(&n, m_szExpression, m_cExpression, szExp, n)) {
			return (BSTR) m_szExpression;
		}
	}
	TCHAR*	GetStdExpression(TCHAR* szStd, int size) {
		return GetStdExpression(szStd, size, m_szExpression, m_cExpression);
	}
	TCHAR* GetStdExpression(TCHAR* szStd, int size, WCHAR* wsz, int wsize) {
		size_t n;
		AllocExp_t(wsize);
#  ifdef UNICODE
		wcscpy(szStd, wsz);
#  else
		if (0 == wcstombs_s(&n, szStd, size, wsz, wsize)) {
			return szStd;
		}
		return NULL;
#  endif
	}
	BOOL	AllocExp_t(int size) {
		if (m_sztExpression && size + 1 <= m_ctExpression) {
			memset(m_sztExpression, 0, m_ctExpression);
			return TRUE;
		}

		if (m_sztExpression) {
			delete [] m_sztExpression;
			m_ctExpression = 0;
		}

		size += 10;
		if (size < 256)
			size = 256;
		m_sztExpression = new TCHAR[size];
		m_ctExpression = size;
		memset(m_sztExpression, 0, size);
		return TRUE;
	}
	void	FreeExp_t() {
		if (m_sztExpression)
			delete [] m_sztExpression;
		m_sztExpression = NULL;
		m_ctExpression = 0;
	}

protected:
	TCHAR*			m_sztExpression;
	size_t			m_ctExpression;
	WCHAR*			m_szExpression;
	size_t			m_cExpression;
};

/*******************
 * Visual Studio 6 *
 *******************/
class CViaDevStudio : CViaCmds {
public:
	CViaDevStudio() :CViaCmds() {
		m_bGetProc = false;
	}
	CViaDevStudio(PVOID pApp) 
		:CViaCmds(pApp) { 
		m_bGetProc = false; 
		Init(pApp);
	}
	virtual ~CViaDevStudio() {
		Release();
	}

	virtual BOOL	Init(PVOID pApp);
	virtual void	Release();
	virtual BOOL	Evaluate(char* exp, PVOID value, VIA_DATATYPE type = VIA_INT);
	virtual BOOL	Evaluate(char* exp, TCHAR* value, int size);
	virtual	BOOL	ReadFromMemory(PBYTE pDst, PBYTE pSrc, long size);

protected:
	bool			findCurrentProcess();

protected:
	IApplication* m_pApplication;
	PROCESSENTRY32 m_proc;
	bool		m_bGetProc;
};

/********************************
 * Visual Studio .Net/2005/2008 *
 ********************************/
class CViaVisualStudio : CViaCmds {
public:
	CViaVisualStudio() :CViaCmds() {m_pApplication = NULL;}
	CViaVisualStudio(PVOID pApp) :CViaCmds(pApp) {m_pApplication = NULL;}
	virtual ~CViaVisualStudio() {
		Release();
	}

	virtual BOOL	Init(PVOID pApp) = 0;
	virtual void	Release();
	virtual BOOL	Evaluate(char* exp, PVOID value, VIA_DATATYPE type = VIA_INT);
	virtual BOOL	Evaluate(char* exp, TCHAR* value, int size);
	virtual	BOOL	ReadFromMemory(PBYTE pDst, PBYTE pSrc, long size);

protected:
	CComPtr<EnvDTE::_DTE> m_pApplication;
	//EnvDTE::_DTE *m_pApplication;
};

/********************************
 * Visual Studio .Net *
 ********************************/
class CViaVisualStudio_2003 : CViaVisualStudio {
public:
	CViaVisualStudio_2003() : CViaVisualStudio() {}
	CViaVisualStudio_2003(PVOID pApp) : CViaVisualStudio(pApp) {
		Init(pApp);
	}
	virtual ~CViaVisualStudio_2003() {}

	virtual BOOL	Init(PVOID pApp);
};

/********************************
 * Visual Studio 2005/2008 *
 ********************************/
class CViaVisualStudio_2005 : CViaVisualStudio {
public:
	CViaVisualStudio_2005() : CViaVisualStudio() {}
	CViaVisualStudio_2005(PVOID pApp) : CViaVisualStudio(pApp) {
		Init(pApp);
	}
	virtual ~CViaVisualStudio_2005() {}

	virtual BOOL	Init(PVOID pApp);
};

#endif//VIA_COMMANDS_INTERNAL_H__